const reg_val = /\{\{(.+?)\}\}/;

class MVVM {
  constructor(el, data) {
    this.el = document.querySelector(el);
    // this._data = data;
    // this.data = {}; // 保存数据
    this.data = data;
    this.domPool = {}; // dom池 保存数据对应的dom

    this.init();
  }

  init() {
    // 数据响应式
    this.initData();
    // dom事件
    this.initDom();
  }

  initDom() {
    this.bindDom(this.el); // 先绑定dom
    this.bindInput(this.el); // 再绑定数据

    console.log(this.domPool);
  }

  initData() {
    const _this = this;

    this.data = new Proxy(this.data, {
      get (target, key) {
        return Reflect.get(target, key);
      },
      set (target, key, value) {
        _this.domPool[key].innerHTML = value;
        return Reflect.set(target, key, value);
      }
    })

    // for (let key in this._data) {
    //   Object.defineProperty(this.data, key, {
    //     get() {
    //       return _this._data[key];
    //     },
    //     set(newVal) {
    //       _this._data[key] = newVal;
    //       _this.domPool[key].innerHTML = newVal;
    //     }
    //   })
    // }
    // console.log(this.data);
  }

  bindDom(el) { // 利用递归 获取dom
    const childNodes = el.childNodes;

    childNodes.forEach(item => {
      if (item.nodeType === 3) { // 文本节点(空格也属于文本节点)
        const _value = item.nodeValue;
        
        if (_value.trim().length) { // 排除空格
          const _isValid = reg_val.test(_value);
          // 判断 {{ }} 里是否有值
          if (_isValid) { // 获取 {{ xxx }} 里面的值
            // console.log(_value);
            const _key = _value.match(reg_val)[1].trim();
            // console.log(_key);
            this.domPool[_key] = item.parentNode; // 拿到包裹{{ xxx }}的节点(父节点)
            item.parentNode.innerText = this.data[_key] || ''
          }
        }
      }

      item.childNodes && this.bindDom(item); // 如果存在子节点就继续往下找
    })
  }

  bindInput(el) {
    const _allInputs = document.querySelectorAll('input');

    _allInputs.forEach(input => {
      // 获取v-model属性 获取dom输入后的值
      const _vModel = input.getAttribute('v-model');
      // console.log(_vModel);
      if (_vModel) {
        input.addEventListener('keyup', this.handleInput.bind(this, _vModel, input), false);
      }
    })
  }

  handleInput(key, input) {
    // const _value = input.value.trim();
    const _value = input.value;
    this.data[key] = _value;
  }

  setData(key, value) { // 设置数据
    this.data[key] = value;
  }
}


